package com.elitel.common.mongodb;

import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.data.annotation.Id;
//import org.springframework.data.mongodb.core.mapping.TimeSeries;

import lombok.Data;

/**
 * Here is time series for record call interface relative condition
 * data structure three body
 * 1. request relative info
 * 2. user relative info
 * 3. response relative info
 **/
//@TimeSeries(collection="callInterfaceRecord", timeField = "timestamp")
@Data
public class GeneralCallInterfaceRecord{

    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:ss:mm");
    private static final Map<String,String>  businessServiceTypeMap = new HashMap<>();

    private static final String DocSearchServicePrefix = "/business/docSearchServer/docTextSearch";
    private static final String ScriptQueryServicePrefix = "/business/multipleServer/multipleTableServer";
    private static final String MasterSlaveTableMasterQueryServicePrefix = "/business/extMasterServer/queryMasterTableList";
    private static final String MasterSlaveTableSlaveQueryServicePrefix = "/business/extMasterServer/querySlaveTBbyMasterID";
    private static final String ReportQueryService = "/business/singleReportServer/singleReportShow";
    private static final String DataSearchService = "/business/searchServer/fullTextSearch";
    private static final String SingleTableQueryService = "/business/singleServer/querySingleTB";
    private static final String StatisticsQueryService = "/business/censusTab/getCensusTableing";
    private static final String SingleEditAddService = "/business/singleEditServer/singleAdd";
    private static final String SingleEditUpdateService = "/business/singleEditServer/singleUpdate";
    private static final String SingleEditDeleteService = "/business/singleEditServer/singleDel";
    private static final String ResourceTreeQueryService = "/business/execute/selectTreeConfig";

    static{
        businessServiceTypeMap.put(DocSearchServicePrefix, "文档检索服务");
        businessServiceTypeMap.put(DataSearchService, "数据检索服务");
        businessServiceTypeMap.put(ScriptQueryServicePrefix, "脚本查询服务");
        businessServiceTypeMap.put(MasterSlaveTableMasterQueryServicePrefix, "主从表(主)查询服务");
        businessServiceTypeMap.put(MasterSlaveTableSlaveQueryServicePrefix, "主从表(从)查询服务");
        businessServiceTypeMap.put(ReportQueryService, "报表查询服务");
        businessServiceTypeMap.put(SingleTableQueryService, "单表查询服务");
        businessServiceTypeMap.put(StatisticsQueryService, "统计查询服务");
        businessServiceTypeMap.put(SingleEditAddService, "单表编辑(新增)服务");
        businessServiceTypeMap.put(SingleEditUpdateService, "单表编辑(修改)服务");
        businessServiceTypeMap.put(SingleEditDeleteService, "单表编辑(删除)服务");
        businessServiceTypeMap.put(ResourceTreeQueryService, "资源树查询服务");
    }


    // here is in mongodb id
    // here is belong mongodb server record assign value into here
    @Id
    private String id;
    private Instant timestamp;

    // start record
    private long recordStartTime;
    private long executeTime;
    private String requestCompleteTime;
    private String serviceID;
    private String serviceType;


    // Request relative info
    // first should record request uri
    // and request ip (source ID (it's good idea))
    // request parameter (1. serviceID 2. left parameter) record request GET or POST method
    private String requestUrl;
    private String requestMethod;
    private Map<String, String[]> requestParameters;

    // here is user relative info
    private String userId;
    private String userName;

    // here is response relative info
    private int responseStatusCode;
    // success is null , exception record e.getMessage()
    private String exceptionMessage;

    public static GeneralCallInterfaceRecord startRecordIfNecessary(HttpServletRequest request){
        if(request == null)
            return null;

        String requestUri = request.getRequestURI();
        System.out.println(requestUri);
        if(!checkPathBelongBussinessService(requestUri))
            return null;

        GeneralCallInterfaceRecord record = new GeneralCallInterfaceRecord();
        record.recordStartTime = System.currentTimeMillis();
        record.timestamp = Instant.now();
        record.requestUrl = request.getRequestURL().toString();
        record.requestMethod = request.getMethod();
        record.serviceType = businessServiceTypeMap.get(requestUri);
        record.requestParameters = request.getParameterMap();
        String[] parameterValues = request.getParameterValues("serviceID");
        if(parameterValues != null)
            record.serviceID = parameterValues[0];

        return record;
    }

    public void setResponseRelativeInfo(HttpServletResponse response){
        if(response == null)
            return;

        endRecord(response.getStatus(), "");
    }

    public void endRecord(int responseStatusCode, String exceptionMessage){
        this.responseStatusCode = responseStatusCode;
        this.executeTime = System.currentTimeMillis() - recordStartTime;
        this.requestCompleteTime = sdf.format(new Date());
        this.exceptionMessage = exceptionMessage;
    }

    public void setExceptionMessage(Exception e){
        if(e == null) return;
        endRecord(500, e.getMessage());
    }

    public static boolean checkPathBelongBussinessService(String requestUri){
        return businessServiceTypeMap.containsKey(requestUri);

    }
}
